package com.ls.rbac.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ls.rbac.config.Result;
import com.ls.rbac.entity.Dept;
import com.ls.rbac.entity.vo.DeptVo;
import com.ls.rbac.service.IDeptService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import io.swagger.v3.oas.annotations.Parameter;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import java.util.List;

/**
 * @author liusheng
 * @since 2025-06-27
 */
@RestController
@RequestMapping("/dept")
@Tag(name = "部门管理模块",description = "部门管理")
public class DeptController {

    @Resource
    private IDeptService deptService;

    @Operation(summary = "部门列表", description = "获取部门列表")
    @GetMapping("/list")
    @PreAuthorize("hasAuthority('sys:dept:list')")
    public Result<List<Dept>> list(String deptName) {
        try {
            LambdaQueryWrapper<Dept> queryWrapper = new LambdaQueryWrapper<>();
            if (ObjectUtil.isNotEmpty(deptName)) {
                queryWrapper.like(Dept::getDeptName, deptName);
            }
            queryWrapper.orderByAsc(Dept::getOrderNum);
            List<Dept> deptList = deptService.list(queryWrapper);
            return Result.success(deptList);
        } catch (Exception e) {
            return Result.fail("获取部门列表失败：" + e.getMessage());
        }
    }

    @Operation(summary = "部门树", description = "获取部门树形结构")
    @GetMapping("/tree")
    @PreAuthorize("hasAuthority('sys:dept:list')")
    public Result<List<Dept>> tree() {
        try {
            List<Dept> deptTree = deptService.getDeptTreeAll();
            return Result.success(deptTree);
        } catch (Exception e) {
            return Result.fail("获取部门树失败：" + e.getMessage());
        }
    }

    @Operation(summary = "部门详情", description = "根据ID获取部门详情")
    @GetMapping("/{id}")
    @PreAuthorize("hasAuthority('sys:dept:list')")
    public Result<Dept> getById(@Parameter(description = "部门ID") @PathVariable Integer id) {
        try {
            Dept dept = deptService.getById(id);
            if (dept == null || dept.getDeleted() == 1) {
                return Result.fail(404, "部门不存在");
            }
            return Result.success(dept);
        } catch (Exception e) {
            return Result.fail("获取部门详情失败：" + e.getMessage());
        }
    }

    @Operation(summary = "添加部门", description = "新增部门信息")
    @PostMapping("/add")
    @PreAuthorize("hasAuthority('sys:dept:add')")
    public Result<Boolean> add(@RequestBody DeptVo deptVo) {
        try {
            if (ObjectUtil.isEmpty(deptVo.getDeptName())) {
                return Result.fail("部门名称不能为空");
            }
            Dept dept = BeanUtil.copyProperties(deptVo, Dept.class);
            if (dept.getPid() == null || dept.getPid() <= 0) {
                dept.setPid(0); // 设置为顶级部门
                dept.setParentName("无");
            } else {
                Dept parentDept = deptService.getById(dept.getPid());
                if (parentDept == null) {
                    return Result.fail("上级部门不存在");
                }
                dept.setParentName(parentDept.getDeptName());
            }
            dept.setDeleted((byte) 0);
            boolean success = deptService.saveDept(dept);
            return success ? Result.success(true, "添加部门成功") : Result.fail("添加部门失败");
        } catch (Exception e) {
            return Result.fail("添加部门失败：" + e.getMessage());
        }
    }

    @Operation(summary = "修改部门", description = "更新部门信息")
    @PutMapping("/update")
    @PreAuthorize("hasAuthority('sys:dept:edit')")
    public Result<Boolean> update(@RequestBody DeptVo deptVo) {
        try {
            if (deptVo.getId() == null) {
                return Result.fail("部门ID不能为空");
            }
            Dept dept = deptService.getById(deptVo.getId());
            BeanUtil.copyProperties(deptVo, dept, CopyOptions.create().ignoreNullValue());
            Dept parentDept = deptService.getById(dept.getPid());
            dept.setParentName(parentDept.getDeptName());
            boolean success = deptService.updateDeptById(dept);
            return success ? Result.success(true, "修改部门成功") : Result.fail("修改部门失败");
        } catch (Exception e) {
            return Result.fail("修改部门失败：" + e.getMessage());
        }
    }

    @Operation(summary = "删除部门", description = "根据ID删除部门")
    @DeleteMapping("/{id}")
    @PreAuthorize("hasAuthority('sys:dept:delete')")
    public Result<Boolean> delete(@Parameter(description = "部门ID") @PathVariable Integer id) {
        try {
            boolean success = deptService.removeDeptById(id);
            return success ? Result.success(true, "删除部门成功") : Result.fail("删除部门失败");
        } catch (Exception e) {
            return Result.fail("删除部门失败：" + e.getMessage());
        }
    }


    @Operation(summary = "上级部门", description = "获取所有可选的上级部门，用于部门修改")
    @GetMapping("/parents")
    @PreAuthorize("hasAuthority('sys:dept:list')")
    public Result<List<Dept>> getParentDeptList(@RequestParam(required = false) Integer excludeId) {
        try {
            LambdaQueryWrapper<Dept> queryWrapper = new LambdaQueryWrapper<>();
            if (excludeId != null && excludeId > 0) {
                List<Integer> excludeIds = deptService.getDeptAndChildrenIds(excludeId);
                if (!excludeIds.isEmpty()) {
                    queryWrapper.notIn(Dept::getId, excludeIds);
                }
            }
            List<Dept> deptList = deptService.list(queryWrapper);
            List<Dept> deptTreeParent = deptService.getDeptTreeParent(deptList);
            return Result.success(deptTreeParent);
        } catch (Exception e) {
            return Result.fail("获取上级部门列表失败：" + e.getMessage());
        }
    }


}
